package facade;

import remoteEntity.Fileblob;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import util.HashUtil;

/**
 * FileblobFacade
 *
 * Handles the Fileblob database entities. Has functionality for inserting into
 * and finding BLOBs in the database.
 */
@Stateless
public class FileblobFacade extends AbstractFacade<Fileblob> {

    @PersistenceContext(unitName = "filecityeePU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public FileblobFacade() {
        super(Fileblob.class);
    }

    /**
     * findByDataHash
     *
     * returns the entity for a hash, returns null if the hash is not present in
     * the database.
     *
     * @param hash the has to search for.
     * @return the Fileblob corresponding that hash.
     */
    private Fileblob findByDataHash(String hash) {
        try {
            return (Fileblob) em.createNamedQuery("Fileblob.findByDataHash").
                    setParameter("dataHash", hash).getSingleResult();
        } catch (NoResultException e) {
            return null;
        }

    }

    /**
     * insertBlob
     *
     * Insert or finds (if it already exists) a Fileblob entity.
     *
     * @param bytes the actual BLOB.
     * @return the blob that is persisted in the database.
     */
    public Fileblob insertBlob(byte[] bytes) {
        Fileblob fb = null;

        String hash = HashUtil.getSHA1(bytes, false);
        Fileblob existingFileBlob = findByDataHash(hash);

        if (existingFileBlob == null) {
            // The BLOB is not in the DB
            fb = new Fileblob();

            fb.setDataHash(hash);
            fb.setDataFile(bytes);

            em.persist(fb);
        } else {
            // The BLOB is already in the DB
            fb = existingFileBlob;
        }
        return fb;
    }

    public byte[] getFile(int id) {
        Fileblob fb = em.find(Fileblob.class, id);
        if (fb == null) {
            return new byte[0];
        } else {
            return fb.getDataFile();
        }
    }
}
